package CompareScheme;

import accessstruct.Tool;
import it.unisa.dia.gas.jpbc.Element;
import it.unisa.dia.gas.jpbc.Pairing;
import it.unisa.dia.gas.plaf.jpbc.pairing.PairingFactory;

/**
 L. Zhang, Y. Zhang, Q. Wu, Y. Mu, and F. Rezaeibagha,
 “A Secure and Efficient Decentralized Access Control Scheme Based on Blockchain for Vehicular Social Networks,”
 IEEE Internet of Things Journal, 2022. 17938–17952。
 *
 */
public class paper3 {
    public static long Setup(int attNum){

        Pairing bp = PairingFactory.getPairing("a.properties");//
        long start = System.currentTimeMillis();
        Element g = bp.getG1().newRandomElement().getImmutable();//
        Element alpha = bp.getZr().newRandomElement().getImmutable();//
        Element beta = bp.getZr().newRandomElement().getImmutable();//
        Element y = bp.getZr().newRandomElement().getImmutable();//
        Element a = bp.getZr().newRandomElement().getImmutable();//
        long end = System.currentTimeMillis();
        return end-start;
    }
    public static long KeyGen(int attNum) throws Exception{
        Pairing bp = PairingFactory.getPairing("a.properties");//
        String gid= "1024";
        Element g = bp.getG1().newRandomElement().getImmutable();//
        Element alpha = bp.getZr().newRandomElement().getImmutable();//
        Element beta = bp.getZr().newRandomElement().getImmutable();//
        Element y = bp.getZr().newRandomElement().getImmutable();//
        Element a = bp.getZr().newRandomElement().getImmutable();//
        Element Gid = bp.getZr().newRandomElement().getImmutable();//
        Element z = bp.getZr().newRandomElement().getImmutable();//
        Element galpha = g.powZn(alpha);
        Element gbeta = g.powZn(beta);
        Element gy = g.powZn(y);
        Element ga= g.powZn(a);

        long start = System.currentTimeMillis();
        Element K2gid = bp.getG1().newRandomElement().powZn(y).getImmutable();

        for(int i = 0 ;i<attNum;i++){
            Element r = bp.getZr().newRandomElement().getImmutable();//
            Element t = bp.getZr().newRandomElement().getImmutable();//
            Element K1gid = galpha.powZn((z.mul(a.mul(r).add(Gid))).invert()).getImmutable();
            Element K3gid = r;
            Element K4gid = g.powZn(r);
            Element K5gid = ga.powZn(r.mul(t)).getImmutable();
            byte[] attHash1 = Tool.sha1(Integer.toString(attNum));
            Element fi = bp.getG1().newElementFromHash(attHash1, 0, attHash1.length).getImmutable();
            Element K6gid = fi.powZn(beta).getImmutable();

        }
        long end = System.currentTimeMillis();
        return end-start;
    }

    public static long Encrypt(int attNum)throws Exception{
        Pairing bp = PairingFactory.getPairing("a.properties");//
        String gid= "1024";
        Element g = bp.getG1().newRandomElement().getImmutable();//
        Element alpha = bp.getZr().newRandomElement().getImmutable();//
        Element beta = bp.getZr().newRandomElement().getImmutable();//
        Element y = bp.getZr().newRandomElement().getImmutable();//
        Element a = bp.getZr().newRandomElement().getImmutable();//
        Element Gid = bp.getZr().newRandomElement().getImmutable();//
        Element z = bp.getZr().newRandomElement().getImmutable();//
        Element galpha = g.powZn(alpha);
        Element gbeta = g.powZn(beta);
        Element gy = g.powZn(y);
        Element ga= g.powZn(a);

        Element message = bp.getGT().newZeroElement().getImmutable();//
        long start = System.currentTimeMillis();

        Element  s = bp.getZr().newRandomElement().getImmutable();//
        Element zero = bp.getZr().newZeroElement().getImmutable();//
        Element C0 =message.mul(bp.pairing(g,g).powZn(s)).getImmutable();
        Element d = bp.getZr().newRandomElement().getImmutable();//
        Element C6 = g.powZn(d).getImmutable();
        Element h =g.powZn(a).getImmutable();
        for(int i = 0 ;i<attNum;i++ ){
            Element rx = bp.getZr().newRandomElement().getImmutable();//
            Element lambdax = bp.getZr().newRandomElement().getImmutable();//
            Element omegax = bp.getZr().newRandomElement().getImmutable();//
            byte[] attHash1 = Tool.sha1(Integer.toString(attNum));
            Element hx = bp.getG1().newElementFromHash(attHash1, 0, attHash1.length).getImmutable();
            Element gammai = bp.pairing(gbeta.powZn(d),hx).getImmutable();
            Element C1x = g.powZn(lambdax).mul(ga.powZn(rx)).getImmutable();
            Element C2x = g.powZn(rx.invert()).getImmutable();
            Element C3x = gy.powZn(rx).mul(g.powZn(omegax)).getImmutable();
            Element C4x = hx.powZn(rx).getImmutable();
            Element C5x = ga.powZn(rx.invert()).getImmutable();
        }
        long end = System.currentTimeMillis();
        return end-start;
    }
    public static long Decrypt(int attNum)throws Exception {
        Pairing bp = PairingFactory.getPairing("a.properties");//

        String gid= "1024";
        Element g = bp.getG1().newRandomElement().getImmutable();//
        Element message = bp.getGT().newZeroElement().getImmutable();//
        Element  s = bp.getZr().newRandomElement().getImmutable();//
        Element  z = bp.getZr().newRandomElement().getImmutable();//
        Element C0 =message.mul(bp.pairing(g,g).powZn(s)).getImmutable();
        Element Ctgid =message.mul(bp.pairing(g,g).powZn(s.mul(z.invert()))).getImmutable();
        long start = System.currentTimeMillis();

        Element m = C0.div(Ctgid.powZn(s)).getImmutable();
        long end = System.currentTimeMillis();
        return end-start;
    }

}
